subscribed.event_machine
An event machine structure slightly resembling finite automata.
-
Declaration
structEventMachine(State_, T = void delegate()) if (is(typeof(State_.init)) && (State_.min != State_.max) && isCallable!T);A state machine with simplified transitions - a wrapper around a state collection. State-dependent transitions should be implemented using beforeEach/afterEach hooks. A transition can be canceled by returning
falsefrom the any beforeEach listeners. The machine has an initial state and a set of alternative states (loops are permitted). Any state can transition to any other state (the initial state is unreachable after transitioning away from it).Parameters
State_An enum of available states.
TThe listener type this event contains. Default is
void delegate().Examples
An event machine stores it's state.
enum State { stateA, stateB } alias Machine = EventMachine!State; Machine machine; assert(machine.state == State.stateA, "The machine is not initially in it's default state"); machine.go!(State.stateB)(); assert(machine.state == State.stateB, "The machine does not navigate to other states"); machine.go!(State.stateB)(); assert(machine.state == State.stateB, "The machine does not permit loops"); machine.go!(State.stateA)(); assert(machine.state == State.stateA, "The machine does not navigate to other states");
Examples
An event machine supports enums with negative values.
enum State { stateA = -21, stateB = 3 } alias Machine = EventMachine!State; Machine machine; assert(machine.state == State.stateA, "The machine is not initially in it's default state"); machine.go!(State.stateB)(); assert(machine.state == State.stateB, "The machine does not navigate to other states");
Examples
beforeEach and afterEach run appropriately.
enum State { stateA, stateB } alias Machine = EventMachine!(State, void delegate()); Machine machine; bool beforeEachRan, afterEachRan; machine.beforeEach ~= (oldState, newState) { assert(oldState == State.stateA, "The machine doesn't move from it's initial state"); assert(newState == State.stateB, "The machine doesn't move to a non-initial state"); beforeEachRan = true; return true; }; machine.afterEach ~= (oldState, newState) { afterEachRan = true; assert(oldState == State.stateA, "The machine doesn't move from it's initial state"); assert(newState == State.stateB, "The machine doesn't move to a non-initial state"); }; machine.go!(State.stateB)(); assert(beforeEachRan, "The beforeEach hook has been ran"); assert(afterEachRan, "The afterEach hook has been ran");
Examples
beforeEach can cancel subsequent events.
enum State { stateA, stateB } alias Machine = EventMachine!(State, void delegate()); Machine machine; machine.beforeEach ~= (oldState, newState) { return false; }; machine.on!(State.stateA)(() { assert(false, "The machine moves to stateA despite the failing beforeEach check"); }); machine.go!(State.stateA)();
-
Declaration
aliasState= State_;An alias to the
State_parameter. -
Declaration
aliasEventType= Event!T;The events' type.
-
Declaration
Event!(bool delegate(State, State))beforeEach;The hook to be executed before any transition. If
falseis returned, no transition occurs. -
Declaration
Event!(void delegate(State, State))afterEach;The hook to be executed after a successful transition.
-
Declaration
const Statestate();The active
state. -
Declaration
voidon(State state)(EventType.ListenerType[]listeners...);A function for appending
listenersto the state event. Can also be called using the aliason!#{stateName}, where the state name is a string.Parameters
stateThe state whose event to subscribe to.
EventType.ListenerType[]listenersThe
listenersto append.See Also
subscribed.event.Event.append
-
Declaration
voidoff(State state)(EventType.ListenerType[]listeners...);A function for removing
listenersfrom the state event.Parameters
stateThe state whose event to remove from.
EventType.ListenerType[]listenersThe
listenersto remove.See Also
subscribed.event.Event.append
-
Declaration
voidgo(State state)(EventType.ParamTypesparams);Calls all the registered listeners in order. Can also be called using the alias
go!#{stateName}, where the state name is a string.Parameters
stateThe state to transition to.
EventType.ParamTypesparamsThe param tuple to call the listener with.
Return Value
An array of results from the listeners. If
EventType.ReturnTypeis void, then this function also returns void.See Also
subscribed.event.Event.call